package cn.tramy.pinxian.wind.event.dispatcher

import cn.tramy.pinxian.common.util.logger
import cn.tramy.pinxian.wind.event.annotation.EventHandler
import cn.tramy.pinxian.wind.eventstore.EventStore
import cn.tramy.pinxian.wind.eventstore.domain.model.DomainEvent
import cn.tramy.pinxian.wind.handler.DomainMessageWrap
import cn.tramy.pinxian.wind.handler.dispatch.AbstractCommonDispatcher
import cn.tramy.pinxian.wind.handler.dispatch.interceptor.DispatchInterceptor
import cn.tramy.pinxian.wind.handler.registry.HandlerRegistry
import cn.tramy.pinxian.wind.util.WindApplicationUtil
import java.util.*

class EventDispatcher(handlerRegistry: HandlerRegistry) : AbstractCommonDispatcher(handlerRegistry) {
    companion object {
        private val LOGGER = logger(EventDispatcher::class.java)
    }

    init {
        this.addInterceptor(EventStoreDispatchInterceptor())
    }

    override fun groupName(): String {
        return EventHandler::class.java.name
    }

    private class EventStoreDispatchInterceptor : DispatchInterceptor {
        override fun beforeDispatch(message: Any): Any {
            if (message is DomainMessageWrap) {
                val domainEvent = DomainEvent(UUID.randomUUID().toString(), message.payload, message.payload::class.java, message.aggregateId, message.aggregateType)
                val eventStore = WindApplicationUtil.applicationContext?.getBean(EventStore::class.java)
                eventStore?.appendEvent(domainEvent)
            }
            return message
        }

        override fun afterDispatch(message: Any) {
        }
    }

}
